; Disassembly of the file MONF000_v2.0.bin" ; ; CPU Type: Z80 ; ; Created with dZ80 2.0 ; ; on Monday, 15 of October 2018 at 03:11 PM ; ; Codice originale EPROM LX390 ; ; Commentato da Salvatore Besso ; MSIZE EQU 20 ; questa e le successive quattro righe IOBYTE EQU 03H ; sono relative al CP/M e non c'entrano BIAS EQU (MSIZE-20)*1024 ; nulla con questa EPROM. Probabilmente NDISKS EQU 4 ; il programmatore le ha lasciate da un LISTST EQU 0000H ; altro file sorgente ; CR EQU 0DH LF EQU 0AH FF EQU 0CH DEL EQU 08H SPACE EQU ' ' ; RAMVID EQU 0EC00H ; inizio memoria video 32x16 CURS EQU 081H ; carattere del cursore ; ; Porte MC6847 (controller video) ; KEYBRD EQU 0EAH ; porta tastiera RTRACE EQU 0EBH ; porta ritraccia video ; ; Porte controller disco ; FDDSTA EQU 0D0H ; porta di stato FD1771 (in lettura) FDDCMD EQU FDDSTA ; porta comandi FD1771 (in scrittura) FDDTRK EQU 0D1H ; porta traccia FD1771 FDDSEC EQU 0D2H ; porta settore FD1771 FDDIDL EQU 0D3H ; porta dati FD1771 (quando non è occupato) FDDI20 EQU 0D4H ; porta accesso IC20 scheda LX390 FDDSEL EQU 0D6H ; porta dati scheda LX390 FDDDAT EQU 0D7H ; porta dati FD1771 ; DMA EQU 0080H ; ; Area RAM CP/M ; ; ARAM EQU 040H ; inizio area RAM DISKNO EQU ARAM ; numero del disco corrente TRACK EQU ARAM + ; traccia corrente SECTOR EQU ARAM + 2 ; settore corrente COMAND EQU ARAM + 3 ; ultimo comando inviato al controller disco STATUS EQU ARAM + 4 ; ultimo stato del controller disco DMAAD EQU ARAM + 5 ; indirizzo area di lettura/scrittura FLAG EQU ARAM + 7 ; flag di lettura/scrittura PUNT EQU ARAM + 8 ; posizione corrente del cursore TR0 EQU ARAM + 10 ; traccia corrente del primo disco ; TR1 EQU ARAM + 11 (secondo disco) ; TR2 EQU ARAM + 12 (terzo disco) ; TR3 EQU ARAM + 13 (quarto disco) ; ASEG ORG 1000H .PHASE 0F000H ; JBOOT: JP BEGIN ; inizializzazione JP CI ; (C)onsole (I)nput JP CO ; (C)onsole (O)utput JP HOME ; sposta la testina a traccia zero JP SELDSK ; selezione disco JP SETTRK ; imposta traccia JP SETSEC ; imposta settore JP SETDMA ; imposta DMA JP READ ; lettura da disco JP WRITE ; scrittura da disco JP COMCO ; legge e salva lo stato del controller disco JP COMOU ; invia un comando al controller disco JP CALTRA ; ottiene la locazione della traccia per il disco corrente JP FISTS ; spostamento testina a traccia e settore JP FISED ; selezione disco JP CAROU ; scrive un carattere sullo schermo JP LER ; routine d'errore (reimposta lo stack e scrive un * JP BOOT ; boot da disco JP EXPR ; input parametri delle routine JP TI ; input carattere con eco sullo schermo ; ; ; scrive un carattere sullo schermo ; CO: LD A,C ; A = carattere da scrivere CP 060H ; carattere < 96? JR C,BIP ; si' RES 5,C ; no, azzera bit 5 (converti a maiuscolo) BIP: PUSH AF LD A,C ; A = carattere eventualmente convertito EXX ; scambia HL,DE,BC con Porte alternativi LD HL,(PUNT) ; HL = posizione cursore CP SPACE ; carattere stampabile? JP M,OB11 ; no CALL CAROU ; si', scrivi il carattere INC HL ; incrementa posizione cursore ; scorrimento righe verso l'alto OAF2: LD A,H ; A = byte più significativo posizione cursore CP 0EEH ; schermo pieno? JR NZ,OB09 ; no, continua LD DE,RAMVID ; si', scorri. DE = prima cella della prima riga video LD HL,RAMVID + 32 ; HL = prima cella della seconda riga video LD B,4 ; quattro blocchi di RAM video... ; sposta i blocchi di RAM video SGG: PUSH BC LD BC,32 * 15 ; ...da 120 byte = 480 byte = 32 caratteri * 15 righe LDIP: IN A,(RTRACE) BIT 7,A ; controller in ritraccia video? JR NZ,LDIP ; si' LDIR ; sposta il primo blocco POP BC DJNZ SGG ; ripeti per le volte ancora rimanenti EX DE,HL ; HL = prima cella dell'ultima riga video CALL OB37 ; cancella l'ultima riga LD HL,RAMVID + (32 * 15) ; HL = prima cella dell'ultima riga video ; scrive il carattere semigrafico del cursore OB09: LD A,CURS CALL CAROU LD (PUNT),HL POP AF EXX ; ripristina HL,DE,BC dai Porte alternativi RET ; gestione caratteri non stampabili OB11: CP CR ; RETURN? JR NZ,OB1A ; no CALL OB37 ; si', a capo e cancella riga JR OAF2 ; cancella l'intero schermo OB1A: CP FF ; FORM FEED? JR NZ,OB2E ; no LD HL,RAMVID ; si', HL = prima cella della prima riga video OB21: CALL OB37 ; cancella la riga corrente LD A,H ; A = byte più significativo posizione cursore CP 0EEH ; Superata l'ultima cella di RAM video? JR NZ,OB21 ; no, continua a cancellare righe LD HL,RAMVID ; si'. HL = prima cella della prima riga video JR OB09 ; fine ; cancella carattere a sinistra del cursore OB2E: CP DEL ; DEL? JR NZ,OB09 ; no, nessun carattere legale digitato. Fine LD A,SPACE ; si' CALL CAROU ; scrivi uno spazio DEC HL ; cursore indietro di una posizione JR OB09 ; fine ; cancella dal cursore a fine riga OB37: LD A,SPACE CALL CAROU ; scrivi uno spazio INC HL ; incrementa posizione cursore LD A,L AND 01FH ; ultima cella della riga? JR NZ,OB37 ; no, continua RET ; si', fine ; emissione del carattere CAROU: PUSH AF PUSH BC LD C,A ; C = carattere da scrivere CAR2: IN A,(RTRACE) ; controllo ritraccia video BIT 7,A ; ritraccia in corso? JR NZ,CAR2 ; si' LD (HL),C ; carattere nella locazione video corrente POP BC POP AF RET ; fine ; ; input da tastiera ; CI: IN A,(KEYBRD) ; controllo pressione tasto BIT 7,A ; tasto premuto? JP Z,CI ; no RES 7,A ; solo caratteri < 128 CP 60H ; carattere maiuscolo? JP M,ESCHI ; si' CP 7BH ; carattere minuscolo? JP P,ESCHI ; no RES 5,A ; si', converti a maiuscolo ESCHI: PUSH AF ; salva carattere SUY: IN A,(KEYBRD) ; controllo rilascio tasto BIT 7,A ; tasto rilasciato? JR NZ,SUY ; no POP AF ; si', recupera il carattere RET ; fine ; selezione disco FISED: PUSH AF PUSH BC LD A,(DISKNO) ; A = numero del disco corrente INC A LD B,A XOR A SCF ; CARRY = 1 FIS11: RLA ; ruota A a sinistra con CARRY: A=1, B=2, C=4, D=8 DJNZ FIS11 OUT (FDDSEL),A ; invia l'accumulatore alla porta dati LX390 POP BC POP AF RET ; RETRY EQU 10 ; ; legge il settore di boot ed esegue ; BOOT: LD SP,DMA ; inizializza lo stack LD C,00H ; inizializza traccia e disco CALL SETTRK ; salva la traccia CALL SELDSK ; salva il disco INC A OUT (FDDSEL),A ; invia 01H alla porta dati LX390 (boot solo da disco A:) CALL HOME ; sposta la testina a traccia zero JP NZ,LER ; errore di spostamento LD BC,DMA ; inizializza l'area DMA CALL SETDMA ; salva l'indirizzo del DMA LD C,01H ; inizializza il settore CALL SETSEC ; salva il settore CALL READ ; legge il settore di boot JP NZ,LER ; errore di lettura JP DMA ; esegue la routine di boot ; ; SETTRK: LD A,C LD (TRACK),A ; salva la traccia nell'area RAM RET ; SETSEC: LD A,C LD (SECTOR),A ; salva il settore nell'area RAM RET ; SETDMA: LD (DMAAD),BC ; salva il DMA nell'area RAM RET ; SELDSK: LD A,C LD (DISKNO),A ; salva il disco nell'area RAM RET ; ; invia un comando al controller disco ; COMOU: PUSH AF COMOU1: IN A,(FDDSTA) ; legge la porta di stato BIT 0,A ; bit 0: BUSY JR NZ,COMOU1 POP AF LD (COMAND),A ; salva il comando nell'area RAM OUT (FDDCMD),A ; invia il comando alla porta EX (SP),HL ; un ritardo? EX (SP),HL EX (SP),HL EX (SP),HL RET ; fine ; ; legge lo stato del controller disco ; COMCO: IN A,(FDDSTA) ; legge la porta di stato BIT 0,A ; bit 0: BUSY JR NZ,COMCO LD (STATUS),A ; salva lo stato nell'area RAM RET ; ; ottiene la locazione della traccia per il disco corrente ; CALTRA: LD HL,TR0 LD A,(DISKNO) ADD A,L LD L,A RET ; ; sposta la testina a traccia zero ; HOME: PUSH BC LD B,03H ; tenta tre volte RIH: LD A,07H ; 07H = TYPE I command: RESTORE with verify CALL COMOU ; invia il comando al controller CALL COMCO ; ottiene lo stato del controller AND 018H ; bit 3: CRC error, bit 4: SEEK ERROR JR Z,ESH ; se i due bit sono a zero l'operazione e' riuscita DJNZ RIH ; operazione fallita, ritenta LD A,082H ; errore 2 e bit 7 = 1 JR NOSEEK ; fallito definitivamente ESH: CALL CALTRA ; HL = locazione traccia del disco corrente JR OKSE ; fine ; ; spostamento testina a traccia e settore ; FISTS: PUSH BC LD B,03H ; tenta tre volte CALL CALTRA ; HL = locazione traccia del disco corrente LD A,(HL) ; A = traccia del disco corrente OUT (FDDTRK),A ; inviala alla porta di traccia del controller FIT1: LD A,(SECTOR) ; A = numero di settore OUT (FDDSEC),A ; invialo alla porta di settore del controller LD A,(TRACK) ; A = numero di traccia OUT (FDDDAT),A ; invialo alla porta dati del controller LD A,017H ; 017H = TYPE I command: SEEK with verify CALL COMOU ; invia il comando al controller CALL COMCO ; ottiene lo stato del controller AND 018H ; bit 3: CRC error, bit 4: SEEK ERROR JR Z,OKSE ; se i due bit sono a zero l'operazione e' riuscita CALL HOME ; operazione fallita, riposiziona la testina a traccia zero JR NZ,NOSEEK ; riposizionamento fallito DJNZ FIT1 ; ritenta posizionamento LD A,083H ; errore 3 e bit 7 = 1 JR NOSEEK ; spostamento fallito definitivamente OKSE: IN A,(FDDTRK) ; leggi il numero corrente di traccia LD (HL),A ; salva la traccia nell'area RAM NOSEEK: POP BC BIT 7,A ; Z = 0: operazione riuscita, Z = 1: operazione fallita RET ; ritorna ; ; lettura da disco ; READ: LD A,01H ; flag = 1: lettura JR RW ; scrittura su disco WRITE: XOR A ; flag = 0: scrittura RW: LD (FLAG),A ; salva il flag di lettura/scrittura RIHOP: CALL FISTS ; posiziona la testina JR NZ,VABE ; posizionamento non riuscito LD B,RETRY ; posizionamento riuscito, B = numero di tentativi RIP: LD HL,(DMAAD) ; HL = indirizzo buffer di lettura/scrittura PUSH BC LD BC,80D7H ; B = numero byte da leggere/scrivere (128), C = porta dati = 0D7H (FDDDAT) LD A,(FLAG) ; A = flag di lettura/scrittura BIT 0,A ; scrittura? JR Z,WWW ; si' RRR: LD A,088H ; 088H = TYPE II command: READ single record using IBM format (128 to 1024 bytes) CALL COMOU ; invia il comando al controller LIB: IN A,(FDDSTA) ; ottiene lo stato del controller BIT 1,A ; bit 1: DATA REQUEST JR Z,LIB ; no INI ; legge un blocco di (B) byte, dalla porta (C), nella memoria a partire da (HL) JR NZ,LIB ; Z = 0: operazione terminata JR FIX WWW: LD A,0A8H ; 0A8H = TYPE II command: WRITE single record using IBM format (128 to 1024 bytes) CALL COMOU ; invia il comando al controller LOB: IN A,(FDDSTA) ; ottiene lo stato del controller BIT 1,A ; bit 1: DATA REQUEST JR Z,LOB ; no OUTI ; scrive un blocco di (B) byte, sulla porta (C), dalla memoria a partire da (HL) JR NZ,LOB ; Z = 0: operazione terminata FIX: CALL COMCO ; ottiene lo stato del controller POP BC AND 01FH ; bit 0: BUSY, bit 1: DATA REQUEST, bit 2: LOST DATA, bit 3: CRC ERROR, bit 4: RECORD NOT FOUND JR Z,VABE ; si', termina DJNZ RIP ; no, riprova fino al numero di volte specificato in RETRY LD A,(FLAG) ; ottieni il flag di lettura/scrittura BIT 7,A ; bit 7 = 1? JR NZ,VABE ; si', termina SET 7,A ; no, imposta a 1 il bit 7 per terminare dopo quest'ultimo tentativo LD (FLAG),A ; salva il flag CALL HOME ; posiziona la testina a traccia zero JR NZ,VABE ; se il posizionamento non riesce, termina JR RIHOP ; ripete un'altra volta, poi il bit 7 del flag a 1 fara' terminare comunque VABE: PUSH AF XOR A OUT (FDDSEL),A ; invia 00H alla porta dati LX390, fine accesso al controller POP AF RET ; ritorna ; VER EQU 20 ; ; Comando (I)np: legge un dato da una porta IIO: DEC C ; un solo parametro richiesto CALL EXPR ; ottieni i parametri del comando POP DE ; porta ROP: LD C,'-' CALL CO LD C,E IN A,(C) CALL LBYTE INC E CALL PCHK JR C,START JR ROP ; ; tabella comandi. Sono presenti 19 voci TBL: DW LER ; A: offset = 0 DW BOOT ; B: offset = 2 DW LER ; C: offset = 4 DW DISP ; D: offset = 6 DW LER ; E: offset = 8 DW FILL ; F: offset = 10 DW GOTO ; G: offset = 12 DW HEXN ; H: offset = 14 DW IIO ; I: offset = 16 DW LER ; J: offset = 18 DW LER ; K: offset = 20 DW COEL ; L: offset = 22 DW JBOOT ; M: offset = 24 DW LER ; N: offset = 26 DW OOI ; O: offset = 28 DW LER ; P: offset = 30 DW LER ; Q: offset = 32 DW COES ; R: offset = 34 DW SUBS ; S: offset = 36 ; ; Comando (O)ut: invia un dato a una porta OOI: CALL EXPR ; ottieni i parametri del comando POP DE ; dato da inviare POP BC ; porta OUT (C),E JR START ; VERS: DB CR,LF,00,00,00,'MONITOR V' DB VER/10+'0','.','0' LVER EQU $-VERS ; FIRAM EQU 0ECFFH ; ultima cella RAM video, valore per test memoria ; ; inizializzazione e cancellazione schermo BEGIN: IN A,(FDDSEL) ; input dalla porta dati LX390 NOP NOP NOP LD A,0C3H ; inizializza il jump alla locazione 066H LD (0066H),A LD HL,JBOOT LD (0067H),HL LD HL,RAMVID ; cancella lo schermo LD (PUNT),HL LD BC,1024 LD DE,RAMVID + 1 LD (HL),SPACE LDIR LD HL,FIRAM ; HL = fine memoria video ; trova la quantita' di memoria installata BG0: DEC H ; blocco precedente da 256 byte LD A,(HL) ; A = locazione di memoria CPL ; complementa A LD (HL),A ; prova a scrivere nella locazione di memoria CP (HL) ; confronta A con la locazione scritta CPL ; complementa di nuovo LD (HL),A ; prova a ripristinare il valore originale JR NZ,BG0 ; scrittura non riuscita, continua a provare INC HL ; scrittura riuscita, questo sara' l'indirizzo dello stack LD SP,HL ; la fine della memoria e' anche l'inizio dello stack ; scrive l'intestazione sullo schermo TIT: LD HL,VERS LD D,LVER VER0: LD C,(HL) INC HL CALL CO DEC D JR NZ,VER0 ; inizio interazione con l'utente START: CALL CRLF ; cursore a capo LD C,'.' ; scrive un punto sullo schermo CALL CO ; GTC (Get Table Command): ottieni dalla tabella il comando corrispondente al tasto premuto GTC: CALL TI ; A = codice tasto premuto SUB 'A' ; trasforma a base 0 (A = 0) JP M,START ; rifiuta se e' < A (0) CP 'S'-'A' + 1 ; il valore e' > S (18)? JP P,LER ; si', indica errore ADD A,A ; offset in tabella: A = A * 2 LD HL,TBL ; HL = inizio tabella comandi ADD A,L LD L,A ; ora HL = posizione del comando LD A,(HL) INC HL LD H,(HL) LD L,A ; ora HL contiene l'indirizzo reale del comando LD C,02H ; C = due parametri richiesti dal comando (predefinito) JP (HL) ; esegue il comando ; Comando (G)o: salto incondizionato ad un indirizzo qualsiasi ; Sulla rivista viene erroneamente indicato come salto incondizionato a 0100H GOTO: DEC C ; un solo parametro richiesto CALL EXPR ; ottieni i parametri del comando POP HL ; indirizzo per il salto JP (HL) ; Comando (D)isplay: scrive il contenuto di un'area di memoria DISP: CALL EXPR ; ottieni i parametri del comando POP DE ; indirizzo finale POP HL ; indirizzo iniziale DI0: CALL CRLF ; riga video successiva CALL LADR ; scrive l'indirizzo corrente (16 bit) sullo schermo DI1: CALL BLK ; scrive uno spazio sullo schermo LD A,(HL) CALL LBYTE ; scrive il contenuto della memoria (8 bit) sullo schermo CALL HILO ; aggiorna i contatori JR C,START ; termina se raggiunta la fine LD A,L AND 07H ; raggiunta la fine della riga? JR NZ,DI1 ; no, continua JR DI0 ; si', nuova riga ; Comando (F)ill: riempie un'area di memoria FILL: INC C ; tre parametri richiesti CALL EXPR ; ottieni i parametri del comando POP BC ; valore con cui riempire (in C) POP DE ; indirizzo finale POP HL ; indirizzo iniziale FI0: LD (HL),C ; scrive il valore nella locazione di memoria CALL HILO ; aggiorna i contatori JR NC,FI0 ; continua se non e' arrivato all'ultima locazione JR START ; termina ; Comando (H)ex: somma e differenza esadecimali HEXN: CALL EXPR ; ottieni i parametri del comando POP DE ; secondo valore POP HL ; primo valore CALL CRLF ; riga video successiva PUSH HL ADD HL,DE ; somma CALL LADR ; scrive la somma (16 bit) sullo schermo CALL BLK ; scrive uno spazio sullo schermo POP HL LD A,L ; differenza SUB E LD L,A LD A,H SBC A,D LD H,A CALL LADR ; scrive la differenza (16 bit) sullo schermo JR START ; termina ; Comando (S)ostituisci: modifica locazioni di memoria SUBS: DEC C ; un solo parametro richiesto CALL EXPR ; ottieni i parametri del comando CALL P2C ; caratteri speciali JR C,LER ; RETURN: errore, poiche' manca il nuovo valore POP HL ; HL = indirizzo iniziale SU0: LD A,(HL) ; A = valore originale CALL LBYTE ; scrive il valore originale sullo schermo... LD C,'-' CALL CO ; ...seguito da un trattino CALL PCHK ; richiedi un carattere JR C,JSTA ; se e' RETURN, termina JR Z,SU1 ; se e' uno spazio o una virgola vai alla locazione successiva PUSH HL ; salva l'indirizzo corrente CALL EXF ; richiedi il nuovo valore; A contiene il valore originale POP DE ; DE = nuovo valore (in E) POP HL ; HL = di nuovo l'indirizzo corrente LD (HL),E ; scrivi il valore all'indirizzo corrente LD A,B ; A = ultimo carattere digitato (da PCHK, TI e salvato in EX1) CP CR ; RETURN? JR Z,JSTA ; si', termina SU1: INC HL ; no, vai alla locazione successiva JR SU0 ; continua ; Comando (L)eggi COEL: LD A,01H ; flag = 1: lettura JR RW1 ; Comando (R)egistra COES: XOR A ; flag = 0: scrittura RW1: LD (FLAG),A LD C,04H ; quattro parametri richiesti CALL EXPR ; ottieni i parametri del comando POP BC ; buffer di lettura/scrittura CALL SETDMA POP BC ; settore CALL SETSEC POP BC ; traccia CALL SETTRK POP BC ; disco CALL SELDSK CALL FISED ; seleziona il disco CALL RIHOP ; esegue l'operazione JR Z,JSTA ; routine che scrive un * sullo schermo LER: CALL MEMSIZ ; trova memoria massima LD SP,HL ; usa la memoria massima come inizio dello stack LD C,'*' ; scrive un * sullo schermo CALL CO JSTA: JP START ; punto comune di ritorno per la maggior parte dei comandi ; scrive uno spazio alla posizione corrente del cursore BLK: LD C,SPACE JP CO ; converte un valore nella sua rappresentazione ASCII CONV: ADD A,090H DAA ADC A,040H DAA LD C,A ; valore convertito in C RET ; ritorna ; va all'inizio della riga successiva CRLF: LD C,CR CALL CO LD C,LF JP CO ; input dei parametri: C = numero dei parametri ; i parametri sono resi nello stack EXPR: LD HL,0000H ; inizializza HL EX0: CALL TI ; input di un carattere, A = carattere EX1: LD B,A ; salva l'ultimo carattere digitato CALL NIBBLE ; e' un carattere esadecimale [0..9,A..F]? JR C,EX2 ; no, carattere speciale o altro ; ----------------------------------------- ; immagazzinamento parametro in HL con ; spostamento dei nibble a sinistra ad ogni ; carattere digitato e somma del carattere ; digitato al nibble meno significativo. ; HL puo' ricevere un valore a 8 o a 16 bit ; ; ---------------------- ; A -> 1 5 F 7 <- tasti premuti ; ---------------------- ADD HL,HL ; HL -> 0 2 2A 2BE ADD HL,HL ; HL -> 0 4 54 57C ADD HL,HL ; HL -> 0 8 A8 AF8 ADD HL,HL ; HL -> 0 10 150 15F0 ; ---------------------- OR L ; A = A + L ; ---------------------- LD L,A ; HL -> 1 15 15F 15F7 JR EX0 ; continua input ; STACK prima dello scambio ; -------------------------------------- ; | indirizzo di ritorno (da EXPR o EXF) ; -------------------------------------- ; | ..... ; -------------------------------------- ; | indirizzo corrente (SOLO da Subs) ; -------------------------------------- EX2: EX (SP),HL ; scambio parametro-indirizzo di ritorno ; STACK dopo lo scambio ; -------------------------------------- ; | ultimo parametro digitato ; -------------------------------------- ; | ..... ; -------------------------------------- ; | indirizzo corrente (SOLO da Subs) ; -------------------------------------- PUSH HL ; ripristino indirizzo di ritorno ; STACK dopo il ripristino ; -------------------------------------- ; | indirizzo di ritorno (da EXPR o EXF) ; -------------------------------------- ; | ultimo parametro digitato ; -------------------------------------- ; | ..... ; -------------------------------------- ; | indirizzo corrente (SOLO da Subs) ; -------------------------------------- LD A,B ; recupera l'ultimo carattere digitato CALL P2C ; controllo caratteri speciali JR NC,EX3 ; se non e' RETURN prova altri caratteri speciali DEC C ; RETURN, input parametri completato? JR NZ,LER ; no, errore RET ; si', ritorna EX3: JR NZ,LER ; se non e' una virgola ne' uno spazio, errore DEC C ; tutti i parametri sono stati digitati? JR NZ,EXPR ; no, continua RET ; si', ritorna ; input di un solo valore a 8 bit per il comando (S)ubs ; in realta' e' possibile digitare valori di lunghezza ; arbitraria, ma verra' considerato solo il byte meno ; significativo EXF: LD C,01H LD HL,0000H JR EX1 ; incrementa HL fino a DE ; ritorna con CARRY = 1 per operazione terminata HILO: INC HL LD A,H OR L SCF RET Z ; questo caso si verifica se HL = 0 dopo l'incremento LD A,E ; se L > E il CARRY viene posto a 1 SUB L LD A,D SBC A,H ; se D > H il CARRY viene azzerato, se D = H non viene modificato RET ; converte il valore a 8 bit contenuto nell'accumulatore nella ; sua rappresentazione ASCII e lo scrive sullo schermo HXD: CALL CONV JP CO ; converte il valore a 16 bit contenuto in HL nella sua ; rappresentazione ASCII e lo scrive sullo schermo LADR: LD A,H CALL LBYTE LD A,L ; converte i nibble del valore a 8 bit contenuto nell'accumulatore ; nella sua rappresentazione ASCII e li scrive sullo schermo LBYTE: PUSH AF ; salva l'accumulatore RRCA ; prima il nibble piu' significativo RRCA ; ottenuto ruotando l'accumulatore... RRCA ; ...a destra per quattro volte... RRCA ; ...portando a destra i quattro bit piu' significativi AND 0FH ; ...e azzerando i quattro bit meno significativi CALL HXD ; converte e scrive sullo schermo POP AF ; ripristina l'accumulatore AND 0FH ; ora il nibble meno significativo JR HXD ; converte e scrive sullo schermo ; verifica la massima memoria installata e ritorna il valore in HL MEMSIZ: LD HL,FIRAM ; HL = fine memoria video MEM0: DEC H ; blocco precedente da 256 byte LD A,(HL) ; A = locazione di memoria CPL ; complementa A LD (HL),A ; prova a scrivere nella locazione di memoria CP (HL) ; confronta A con la locazione scritta CPL ; complementa di nuovo LD (HL),A ; prova a ripristinare il valore originale JR NZ,MEM0 ; scrittura non riuscita, continua a provare INC HL ; scrittura riuscita, questo sara' l'indirizzo dello stack RET ; ritorna ; verifica che il numero digitato sia ; compreso in [0..9,A..F], se non lo e' ; ritorna C = 1 ; --------------------------------------------------------------- ; A ---> | '0' | '9' | 'A' | 'F' | '/' | ':' | '@' | 'G' | ; A ---> | 30H | 39H | 41H | 46H | 2FH | 3AH | 40H | 47H | ; --------------------------------------------------------------- ; | A | A | A | A | A | A | A | A | ; --------------------------------------------------------------- NIBBLE: SUB '0' ; SUB '0' | 00H | 09H | 11H | 16H | FFH | 0AH | 10H | 17H | RET C ; | | | | | | | | | ADD A,'0'-'G' ; ADD A,'0'-'G' | E9H | F2H | FAH | FFH | C | F3H | F9H | 00H | RET C ; | | | | | | | | | ADD A,06H ; ADD A,06H | EFH | F8H | 00H | 05H | C | F9H | FFH | C | JP P,NI0 ; | | | | | | | | | ADD A,07H ; ADD A,07H | F6H | FFH | P | P | C | 00H | 06H | C | RET C ; | | | | | | | | | NI0: ADD A,0AH ; ADD A,0AH | 00H | 09H | 0AH | 0FH | C | C | C | C | OR A ; --------------------------------------------------------------- ; P: PARITY C: CARRY RET ; ritorna ; richiede un carattere, lo scrive sullo schermo e ne controlla il tipo PCHK: CALL TI P2C: CP SPACE ; e' uno spazio? RET Z ; si', ritorna CP ',' ; e' una virgola? RET Z ; si', ritorna CP CR ; e' un RETURN? SCF ; imposta carry CCF ; azzera carry RET NZ ; carattere normale, ritorna senza carry SCF ; RETURN... RET ; ...ritorna con carry ; richiede un carattere all'utente (ritorno in A) e lo scrive sullo schermo TI: CALL CI AND 07FH ; solo caratteri contenuti nei primi 128 byte della tavola ASCII PUSH BC LD C,A CALL CO ; scrive il carattere sullo schermo LD A,C ; A = carattere eventualmente convertito a maiuscolo POP BC RET ; ritorna ; .DEPHASE ; ; END